﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TiaoTiaoCode.Common.Extensions
{
    /// <summary>
    /// 列表类扩展
    /// </summary>
    public static class EnumerableEx
    {
        /// <summary>
        /// 列表是否有数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TiaoTiaoHasData<T>(this IList<T>? list)
        {
            return list != null && list.Count > 0;
        }

        /// <summary>
        /// 列表是否有数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TiaoTiaoHasData<T>(this IEnumerable<T>? list)
        {
            return list != null && list.AsQueryable().Count() > 0;
        }

        /// <summary>
        /// 列表是否无数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TiaoTiaoNoData<T>(this IList<T>? list)
        {
            return list == null || list.Count <= 0;
        }

        /// <summary>
        /// 列表是否无数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static bool TiaoTiaoNoData<T>(this IEnumerable<T>? list)
        {
            return list == null || list.AsQueryable().Count() <= 0;
        }

        /// <summary>
        /// 多维列表转单维列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static IEnumerable<T> TiaoTiaoToFloor<T>(this IEnumerable<IEnumerable<T>> list)
        {
            var result = new List<T>();

            foreach (var lst in list)
            {
                foreach (var item in lst)
                {
                    result.Add(item);
                }
            }

            return result;
        }

        /// <summary>
        /// 去重
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TKey"></typeparam>
        /// <param name="source"></param>
        /// <param name="keySelector"></param>
        /// <returns></returns>
        public static IEnumerable<TSource> TiaoTiaoDistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            HashSet<TKey> seenKeys = new HashSet<TKey>();
            foreach (TSource element in source)
            {
                if (seenKeys.Add(keySelector(element)))
                {
                    yield return element;
                }
            }
        }

        /// <summary>
		/// 拷贝当前的实例数组，是基于引用层的浅拷贝，如果类型为值类型，那就是深度拷贝，如果类型为引用类型，就是浅拷贝
		/// </summary>
		/// <typeparam name="T">类型对象</typeparam>
		/// <param name="value">数组对象</param>
		/// <returns>拷贝的结果内容</returns>
		public static T[] TiaoTiaoCopyArray<T>(this T[] value)
        {
            if (value == null) return null!;
            T[] buffer = new T[value.Length];
            Array.Copy(value, buffer, value.Length);
            return buffer;
        }

        /// <summary>
        /// 数组移除操作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="lengthLeft">左边移除数量</param>
        /// <param name="lengthRight">右边移除数量</param>
        /// <returns></returns>
        public static T[] TiaoTiaoArrayRemoveDouble<T>(this T[] value,int lengthLeft,int lengthRight)
        {
            if (value == null) return null!;
            if (value.Length <= (lengthLeft + lengthRight)) return new T[0];

            T[] buffer = new T[value.Length - lengthLeft - lengthRight];
            Array.Copy(value, lengthLeft, buffer, 0, buffer.Length);

            return buffer;
        }

        /// <summary>
        /// 移除数组从头开始的length个
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static T[] TiaoTiaoArrayRemoveBegin<T>(this T[] value, int length) => value.TiaoTiaoArrayRemoveDouble(length, 0);

        /// <summary>
        /// 移除数组从尾开始的的length个
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static T[] TiaoTiaoArrayRemoveLast<T>(this T[] value, int length) => value.TiaoTiaoArrayRemoveDouble(0, length);
    }
}
